package com.kun.companion.core.ui.tree;

import com.kun.companion.Main;
import javafx.application.HostServices;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.scene.Node;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.StackPane;
import javafx.stage.Window;

import java.io.File;
import java.nio.file.*;
import java.util.Arrays;
import java.util.Comparator;

/**
 * 文件系统专用树形视图实现
 * <p>
 * 功能特性:
 * 1. 展示文件系统层级结构
 * 2. 自动识别常见文件类型图标
 * 3. 支持右键上下文菜单操作
 * 4. 实时监听目录变化
 * 5. 文件大小智能显示
 * <p>
 * 使用示例:
 * FileTreeView fileTree = new FileTreeView(Paths.get("/"));
 */
public class FileTreeView extends BaseTreeView<File> {

    /* ------------------------ 构造方法 ------------------------ */

    public FileTreeView(Path rootPath) {
        super(new FileTreeItem(rootPath.toFile()));
        initFileSpecificComponents();
    }

    /* ------------------------ 初始化方法 ------------------------ */

    private void initFileSpecificComponents() {
        // 配置文件专用样式
        getStyleClass().add("file-tree");
        getStylesheets().add("data:text/css;charset=UTF-8," + fileCSS);
        // 自定义单元格工厂
        setCellFactory(tv -> new FileTreeCell());

        // 注册目录监听器
        registerFileWatcher();
    }

    /* ------------------------ 文件树节点实现 ------------------------ */

    private static class FileTreeItem extends BaseTreeItem<File> {
        private final FileSystemWatcher watcher = new FileSystemWatcher();

        public FileTreeItem(File file) {
            super(file);
            initFileItem();
        }

        private void initFileItem() {
            // 设置节点图标
            nodeIcon.bind(Bindings.createObjectBinding(
                    () -> createFileIcon(getValue()),
                    expandedProperty()
            ));

            // 标记目录节点
            if (getValue().isDirectory()) {
                getChildren().add(new PlaceholderItem()); // 添加占位节点
            }
        }

        @Override
        protected void lazyLoadChildren() {
            if (!loaded.get() && getValue().isDirectory()) {
                loadActualChildren();
                startDirectoryWatch();
            }
        }

        private void loadActualChildren() {
            getChildren().clear();
            File[] files = getValue().listFiles();
            if (files != null) {
                Arrays.stream(files)
                        .sorted(Comparator.comparing(File::isDirectory).reversed())
                        .map(FileTreeItem::new)
                        .forEach(getChildren()::add);
            }
            loaded.set(true);
        }

        private void startDirectoryWatch() {
            watcher.watchDirectory(getValue().toPath(), () ->
                    Platform.runLater(this::refreshChildren));
        }

        //++++++++ 新增refreshChildren方法 ++++++++//
        private void refreshChildren() {
            if (getValue().isDirectory()) {
                loadActualChildren();
            }
        }

        private Node createFileIcon(File file) {
            StackPane icon = new StackPane();
            icon.getStyleClass().addAll("file-icon",
                    file.isDirectory() ? "folder" : getFileTypeClass(file));
            return icon;
        }

        private String getFileTypeClass(File file) {
            String[] parts = file.getName().split("\\.");
            if (parts.length > 1) {
                return parts[parts.length - 1].toLowerCase();
            }
            return "generic";
        }
    }

    /* ------------------------ 文件单元格实现 ------------------------ */

    private class FileTreeCell extends BaseTreeCell<File> {
        private final ContextMenu contextMenu = new ContextMenu();

        public FileTreeCell() {
            configureContextMenu();
        }

        @Override
        protected void configureCellContent(File file) {
            super.configureCellContent(file);
            addFileSpecificFeatures(file);
        }

        private void addFileSpecificFeatures(File file) {
            // 添加文件大小标签
            if (!file.isDirectory()) {
                Label sizeLabel = new Label(formatFileSize(file.length()));
                sizeLabel.getStyleClass().add("file-size");
                super.container.getChildren().add(sizeLabel);
            }

            // 右键菜单可见性控制
//            contextMenu.setShowCondition(e -> !isEmpty());
            // 修复右键菜单显示条件：使用标准事件处理器
            contextMenu.setOnShowing(e -> {
                if (isEmpty()) {
                    e.consume();
                }
            });
        }

        private void configureContextMenu() {
            MenuItem open = new MenuItem("打开");
            open.setOnAction(e -> openFile(getItem()));

            MenuItem delete = new MenuItem("删除");
            delete.setOnAction(e -> deleteFile(getItem()));

            contextMenu.getItems().addAll(open, delete);
            setContextMenu(contextMenu);
        }

        private String formatFileSize(long bytes) {
            if (bytes < 1024) {
                return bytes + " B";
            }
            int exp = (int) (Math.log(bytes) / Math.log(1024));
            return String.format("%.1f %sB",
                    bytes / Math.pow(1024, exp), "KMGTPE".charAt(exp - 1));
        }
    }

    /* ------------------------ 文件监听组件 ------------------------ */

    private void registerFileWatcher() {
        // 实现文件系统监听逻辑
        // (此处需实现具体监听逻辑)
    }

    /* ------------------------ 占位节点 ------------------------ */

    private static class PlaceholderItem extends BaseTreeItem<File> {
        public PlaceholderItem() {
            super(null);
        }
    }

    /* ------------------------ 样式扩展 ------------------------ */

    // 文件类型专用样式
    static String fileCSS =
            ".file-tree .folder { -fx-background-color: #4dabf7; }\n" +
                    ".file-tree .pdf { -fx-background-color: #e64980; }\n" +
                    ".file-tree .docx { -fx-background-color: #339af0; }\n" +
                    ".file-tree .generic { -fx-background-color: #adb5bd; }\n" +
                    ".file-size { -fx-text-fill: #868e96; -fx-font-size: 0.9em; }";


    /* ------------------------ 业务方法 ------------------------ */

    private void openFile(File file) {
        if (file.isDirectory()) {
            getSelectionModel().select(getFocusModel().getFocusedIndex());
        } else {
            // 调用系统打开方式
            HostServicesProvider.getHostServices(Main.getAppStage()).showDocument(file.getAbsolutePath());
            System.out.println("调用系统打开方式");
        }
    }

    private void deleteFile(File file) {
        // 实现安全删除逻辑
        // (此处需实现回收站操作)
    }

    //++++++++++++++++++ HostServices工具类 ++++++++++++++++++//
    private static class HostServicesProvider {
        public static HostServices getHostServices(Window window) {
            return (HostServices) window.getProperties()
                    .computeIfAbsent("hostServices", k ->
                            new HostServicesWrapper(window));
        }

        private static class HostServicesWrapper {
            private final Window window;
            private final HostServices hostServices;

            public HostServicesWrapper(Window window) {
                this.window = window;
                // Obtain the actual HostServices instance from the application
                this.hostServices = obtainHostServices();
            }

            private HostServices obtainHostServices() {
                // Replace this with the actual way to obtain HostServices in your application
                // For example, if you have access to the Application instance:
//                return com.sun.javafx.application.PlatformImpl.getApplication().getHostServices();
                return Main.obtainHostServices();
            }

            public void showDocument(String uri) {
                // Delegate to the actual HostServices instance
                hostServices.showDocument(uri);

                // Add custom behavior here if needed
                System.out.println("Opening document: " + uri);
            }
        }
    }

    //++++++++++++++++++ 新增FileSystemWatcher实现 ++++++++++++++++++//
    private static class FileSystemWatcher {
        private WatchService watchService;
        private Thread watchThread;

        public void watchDirectory(Path path, Runnable callback) {
            try {
                watchService = FileSystems.getDefault().newWatchService();
                path.register(watchService,
                        StandardWatchEventKinds.ENTRY_CREATE,
                        StandardWatchEventKinds.ENTRY_DELETE,
                        StandardWatchEventKinds.ENTRY_MODIFY);

                watchThread = new Thread(() -> {
                    try {
                        while (true) {
                            WatchKey key = watchService.take();
                            for (WatchEvent<?> event : key.pollEvents()) {
                                Platform.runLater(callback);
                            }
                            key.reset();
                        }
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
                watchThread.setDaemon(true);
                watchThread.start();
            } catch (Exception e) {
                throw new RuntimeException("Failed to start watcher", e);
            }
        }
    }
}
